import { Component, createVNode, render } from "vue";

declare type ModalHookParams = () => Element | undefined;
declare type ModalProps = Record<string, unknown>;
declare type CloseModal = () => void;
declare type RenderModal = <T extends Component>(modalComponent: T, modalProps?: ModalProps) => void;
declare type ModalState = [CloseModal, RenderModal];

declare const _MODAL_ID_: string;


/**
 * 模态框弹窗
 * ```
 * // 关闭模态框
 * closeModal:()=>void;
 * 
 * // modalComponent 要渲染的模态框组件
 * // modalProps 模态框组件属性
 * renderModal: (modalComponent, modalProps) => void;
 * ```
 * @param teleport 模态框组件挂载的位置
 * @return [`closeModal`, `renderModal`]
*/
export default (teleport?: ModalHookParams): ModalState => {
  let baseContainer: Element | null;
  const getContainer = (teleport?: ModalHookParams | Element): Element => {
    if (teleport) {
      if (typeof teleport === 'function') {
        return getContainer(teleport());
      }
      return teleport;
    }
    if (!baseContainer) {
      if (baseContainer = document.getElementById(_MODAL_ID_)) {
        return baseContainer;
      }
      baseContainer = document.createElement('div');
      baseContainer.role = 'modal';
      baseContainer.id = _MODAL_ID_;
      document.body.appendChild(baseContainer);
    }
    return baseContainer;
  }

  // 关闭模态框
  const closeModal = () => {
    render(null, getContainer(teleport));
    document.body.style.removeProperty('overflow');
  };

  /**
   * 渲染模态框组件
   * @param modalComponent 要渲染的模态框组件
   * @param modalProps 模态框组件属性
  */
  const renderModal: RenderModal = <T extends Component>(
    modalComponent: T,
    modalProps?: ModalProps
  ) => {
    const vNode = createVNode(modalComponent, modalProps);
    render(vNode, getContainer(teleport));
    document.body.style.overflow = 'hidden';
  };

  return [closeModal, renderModal];
}